<?php
/**
 * Author: Dcr
 * Date: 2019/7/16
 * Time: 14:52
 */
namespace dcr;

defined('IN_DCR') or exit('No permission resources.');
//base 根目录
defined('LIB_PATH') or define('LIB_PATH',__DIR__);
class Base
{
    static protected $instance = NULL;
    static protected $config = [];
    static $module;
    static $controller;
    static $method;
    /**
     * 单例模式
     * Base constructor.
     * @param $config
     */
    protected function __construct()
    {
        return $this;
    }

    /**
     * 单例模式
     * @param $config
     * @return Base|null
     */
    static function getInstance($config){
        if( is_null(self::$instance) ){
            self::$config = $config;
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 获取配置
     * @param string $key
     * @return array|mixed
     */
    static function getConfig($key = ''){
        //二维数组配置信息读取 用符号. 做分割符
        if( strpos($key,'.') !== false ){
            $keys = explode('.',$key,2); //只分割两组
            $c1 = $keys[0];
            $c2 = $keys[1] ? $keys[1] : null;
            //二级返回
            if( isset( self::$config[$c1] ) && $c2 ) {
                return isset(self::$config[$c1][$c2]) ? self::$config[$c1][$c2] : null;
            } else {
                return isset(self::$config[$c1]) ? self::$config[$c1] : null;
            }
        }
        //如果有key则返回指定配置信息，否则返回所有配置信息
        return $key ? (isset(self::$config[strtolower($key)]) ? self::$config[strtolower($key)]: null) : self::$config;
    }
    /**
     * 运行框架
     */
    public function run(){
        //自动加载类文件 使用 本类的autoLoader方法
        spl_autoload_register('self::autoLoader');
        //执行错误
        $this->setError();
        //转义请求数据
        $this->addslashesRes();
        //url解析
        $this->route();
    }

    public function route(){
        $pathInfo = isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
        $module = $controller = $method = '';
        if( $pathInfo ){
            $params = explode('/',trim($_SERVER['PATH_INFO'],'/')); //获取pathinfo 的参数
            $module = strtolower(trim($params[0]));             //解析模块
            $controller = isset($params[1]) ? ucfirst(trim($params[1])) : '';            //解析控制器
            $method = isset($params[2]) ? trim($params[2]) : '';                        //解析方法
            unset($params[0]);                                  //把模块个参数销毁
            unset($params[1]);                                  //把控制器参数销毁
            unset($params[2]);                                  //把方法参数销毁
        }

        //获取参数赋值给 $_GET 变量
        $getParams = [];
        if( !empty($params) ){
            //重新整理其他参数
            $params = array_values($params);
            foreach ( $params as $k => $v ){
                //每两个为一对
                if ($k % 2 == 0) {
                    $getParams[$params[$k]] = isset($params[$k+1]) ? $params[$k+1] : '';
                }
            }
            $_GET = array_merge($getParams,$_GET); //合并 $_GET 参数
        }

        if( empty($module) ) $module = self::$config['action']['module'];               //设置默认模块
        if( empty($controller) ) $controller = self::$config['action']['controller'];           //默认控制器
        if( empty($method) ) $method = self::$config['action']['method'];               //默认方法

        self::$module = $module;            //保存当前的模块
        self::$controller = $controller;    //保存当前控制器
        self::$method = $method;        //保存当前方法
        $className = '\\app'.'\\'.$module.'\\controller\\'.$controller.'Controller';    //控制器文件
        if( APP_DEBUG ){
            if( !is_dir(WEB_PATH.'/app/'.$module) ){
                throw new \Exception('<strong>'.$module.'</strong> 模块不存在');
            }
            if( !class_exists($className) ){
                throw new \Exception('模块:'.$module.'，控制器:<strong>'.$controller.'</strong> 不存在');
            }
            if( !method_exists($className,$method) ) {
                throw new \Exception('模块:'.$module.'，控制器:'.$controller.'-><strong>'.$method.'</strong> 方法不存在');
            }
        }
        $obj = new $className;                  //实例化对象
        $obj->$method();                        //执行控制的方法
    }
    /**
     * 自动加载
     * @param $className
     */
    protected function autoLoader($className){
        $file = '';
        if( strpos($className,'\\') !== false ){
            $file = WEB_PATH.'/'. str_replace('\\','/',$className).'.php';
        }
        if( !file_exists($file) && APP_DEBUG){
            throw new \Exception($file.'文件不存在');
        }
        include $file;
    }
    /**
     * 设置错误级别
     */
    protected function setError(){
        if ( APP_DEBUG ){
            error_reporting(E_ALL); // 报告所有PHP错误
            ini_set('display_errors', 'On'); // 开启php错误提示，而且是所有错误提示
        } else {
            error_reporting(E_ALL);
            ini_set('display_errors', 'Off');  // 关闭错误抛出
            ini_set('log_errors', 'On');   // 开启错误日志记录
            ini_set('error_log', WEB_PATH.'/logs/error.log');  // 错误日志记录
        }
    }

    /**
     * 转义常用 预定义变量
     */
    protected function addslashesRes(){
        $_GET = isset($_GET) ? $this->stripSlashesDeep($_GET ) : '';
        $_POST = isset($_POST) ? $this->stripSlashesDeep($_POST ) : '';
        $_COOKIE = isset($_COOKIE) ? $this->stripSlashesDeep($_COOKIE) : '';
        $_SESSION = isset($_SESSION) ? $this->stripSlashesDeep($_SESSION) : '';
    }
    /*
     * 返回一个去除转义反斜线后的字符串（\' 转换为 ' 等等）。双反斜线（\\）被转换为单个反斜线（\）。
     */
    protected function stripslashesDeep($value)
    {
        if( get_magic_quotes_gpc() ){
            $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
        } else {
            $value = is_array($value) ? array_map('stripslashes', $value) : stripslashes($value);
        }
        return $value;
    }

}